package com.pz.cloud.framework.researchProj.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pz.cloud.framework.base.dao.CommonDao;
import com.pz.cloud.framework.base.expection.CustomRuntimeException;
import com.pz.cloud.framework.base.service.BaseServiceImpl;
import com.pz.cloud.framework.business.config.CodeEnum;
import com.pz.cloud.framework.business.config.ModuleEnum;
import com.pz.cloud.framework.business.config.entity.BizConfig;
import com.pz.cloud.framework.business.config.service.IBizConfigService;
import com.pz.cloud.framework.business.researchProj.vo.ResearchProjectVo;
import com.pz.cloud.framework.business.researchProj.vo.ResearchProjectModel;
import com.pz.cloud.framework.business.researchProj.entity.*;
import com.pz.cloud.framework.business.researchProj.service.*;
import com.pz.cloud.framework.business.workflow.annotation.Workflow;
import com.pz.cloud.framework.business.workflow.enums.WorkflowEnum;
import com.pz.cloud.framework.business.workflow.model.WorkflowModel;
import com.pz.cloud.framework.model.AbstractSqlBuilder;
import com.pz.cloud.framework.model.SqlBuilder;
import com.pz.cloud.framework.researchProj.callback.ResearchProjectCallback;
import com.pz.cloud.framework.researchProj.mapper.ResearchProjectMapper;
import com.pz.cloud.framework.util.BizUtil;
import com.pz.cloud.framework.util.WorkflowUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @Description: 科研项目
 * @Author: jeecg-boot
 * @Date:   2020-12-13
 * @Version: V1.0
 */
@Service
@Transactional
public class ResearchProjectServiceImpl extends BaseServiceImpl<ResearchProjectMapper, ResearchProject> implements IResearchProjectService {

    @Autowired
    private CommonDao commonDao;

    @Autowired
    private IResearchProjectDirectorService directorService;

    @Autowired
    private IResearchProjectInstructorService instructorService;

    @Autowired
    private IResearchProjectMemService memService;

    @Autowired
    private IResearchProjectFundService fundService;

    @Autowired
    private IResearchProjectDetailService detailService;

    @Autowired
    private IBizConfigService bizConfigService;

    @Override
    public IPage<ResearchProjectModel> getModelPage(ResearchProject entity) {
        AbstractSqlBuilder sqlBuilder = SqlBuilder.init("select p.*,pm.members,pd.std_no,pd.college,pd.major,pd.grade,pd.clazz,pd.sex from ")
                .append(entity.getTableName()).append(" p")
                .append(" left join (select group_concat(name) as members, project_id from ").appendTable(ResearchProjectMem.class)
                .append(" group by project_id) pm on p.id = pm.project_id ")
                .append(" left join ").appendTable(ResearchProjectDirector.class).append(" pd on p.id = pd.project_id")
                .orderBy("p.id desc")
                .returnType(ResearchProjectModel.class)
                .page(entity)
                .joinCondition(entity,"p")
                .filterDataScope("p");
        String college = entity.getCollege();
        if (!StringUtils.isEmpty(college)) {
            sqlBuilder.append(" and pd.college like :college").setParmsLike("college", college);
        }
        if (entity.getActStatus()==null) {
            sqlBuilder.append(" and p.act_status < :actStatus").setParms("actStatus", WorkflowEnum.ProcessStatus.流程结束.getStatus());
        }
        return commonDao.findPage(sqlBuilder);
    }

    @Override
    @Transactional
    public void add(ResearchProjectVo req) {
        BizConfig bizConfig = bizConfigService.getByModuleAndCode(ModuleEnum.RESEARCH_PROJECT.name(), CodeEnum.TIME_RANGE.name());
        String timeRange = bizConfig.getValue();
        if (StringUtils.isEmpty(timeRange)) {
            throw new CustomRuntimeException("科研项目申报时间未配置");
        }

        String[] split = timeRange.split("-");
        if (split.length != 2) {
            throw new CustomRuntimeException("科研项目申报时间配置格式错误");
        }

        String begin = split[0];
        String end = split[1];
        try {
            long now = System.currentTimeMillis();
            if (!StringUtils.isEmpty(begin)) {
                if (Long.parseLong(begin) > now) {
                    throw new CustomRuntimeException("未到申报时间");
                }
            }
            if (!StringUtils.isEmpty(end)) {
                if (Long.parseLong(end) < now) {
                    throw new CustomRuntimeException("已过申报时间");
                }
            }
        } catch (NumberFormatException e) {
            log.error("解析时间出错", e);
            throw new CustomRuntimeException("科研项目申报时间配置格式错误");
        }

        edit(req);
    }

    @Override
    @Transactional
    public void edit(ResearchProjectVo req) {
        ResearchProject researchProject = req.getResearchProject();
        if (req.getDirector() != null) {
            researchProject.setDirector(req.getDirector().getName());
        }
        if (req.getInstructor() != null) {
            researchProject.setInstructor(req.getInstructor().getName());
        }

        saveOrUpdate(researchProject);
        ResearchProjectDirector director = req.getDirector();
        if (director != null) {
            director.setProjectId(researchProject.getId());
            directorService.saveOrUpdate(director);
        }
        else {
            directorService.removeByProjectId(researchProject.getId());
        }
        ResearchProjectInstructor instructor = req.getInstructor();
        if (instructor != null) {
            instructor.setProjectId(researchProject.getId());
            instructorService.saveOrUpdate(instructor);
        }
        else {
            instructorService.removeByProjectId(researchProject.getId());
        }
        List<ResearchProjectDetail> details = req.getDetails();
        detailService.removeByProjectId(researchProject.getId());
        if (details != null) {
            details.forEach(detail -> {
                detail.setProjectId(researchProject.getId());
                detailService.saveOrUpdate(detail);
            });
        }

        List<ResearchProjectFund> funds = req.getFunds();
        fundService.removeByProjectId(researchProject.getId());
        if (funds != null) {
            funds.forEach(fund -> {
                fund.setProjectId(researchProject.getId());
                fundService.saveOrUpdate(fund);
            });
        }
        List<ResearchProjectMem> members = req.getMembers();
        memService.removeByProjectId(researchProject.getId());
        if (members != null) {
            members.forEach(member -> {
                member.setProjectId(researchProject.getId());
                memService.saveOrUpdate(member);
            });
        }
        WorkflowModel workflowModel = req.getWorkflowModel();
        researchProject.setWorkflowModel(workflowModel);
        researchProject.getWorkflowModel().setHandlerId(instructor==null?null:instructor.getInstructorId());
        researchProject.getWorkflowModel().setCallback(BizUtil.getBeanName(ResearchProjectCallback.class));
        WorkflowUtil.submit(researchProject);
    }

    @Override
    public ResearchProjectVo getVoById(String id) {
        ResearchProject researchProject = getById(id);
        if (researchProject == null) {
            throw new CustomRuntimeException("记录不存在");
        }
        ResearchProjectDirector director = directorService.getByProjectId(id);
        ResearchProjectInstructor instructor = instructorService.getByProjectId(id);
        List<ResearchProjectMem> mems = memService.getByProjectId(id);
        List<ResearchProjectFund> funds = fundService.getByProjectId(id);
        List<ResearchProjectDetail> details = detailService.getByProjectId(id);
        ResearchProjectVo researchProjectVo = new ResearchProjectVo();
        researchProjectVo.setResearchProject(researchProject);
        researchProjectVo.setDirector(director);
        researchProjectVo.setInstructor(instructor);
        researchProjectVo.setFunds(funds);
        researchProjectVo.setMembers(mems);
        researchProjectVo.setDetails(details);

        return researchProjectVo;
    }
}
